Proper connect_port
[juce-lv2.git] / juce / source / extras / the jucer / src / model / documents / jucer_ButtonDocument.cpp
blobdf9ae4a973e61ab584aaee14cb7b4cbc6765836d
1 /*
2 ==============================================================================
4 This file is part of the JUCE library - "Jules' Utility Class Extensions"
5 Copyright 2004-11 by Raw Material Software Ltd.
7 ------------------------------------------------------------------------------
9 JUCE can be redistributed and/or modified under the terms of the GNU General
10 Public License (Version 2), as published by the Free Software Foundation.
11 A copy of the license is included in the JUCE distribution, or can be found
12 online at www.gnu.org/licenses.
14 JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16 A PARTICULAR PURPOSE. See the GNU General Public License for more details.
18 ------------------------------------------------------------------------------
20 To release a closed-source product which uses JUCE, commercial licenses are
21 available: visit www.rawmaterialsoftware.com/juce for more information.
23 ==============================================================================
26 #include "../../jucer_Headers.h"
27 #include "jucer_ButtonDocument.h"
29 //==============================================================================
30 static const int normalOff = 0;
31 static const int overOff = 1;
32 static const int downOff = 2;
33 static const int normalOn = 3;
34 static const int overOn = 4;
35 static const int downOn = 5;
36 static const int background = 6;
39 //==============================================================================
40 ButtonDocument::ButtonDocument()
42 paintStatesEnabled [normalOff] = true;
43 paintStatesEnabled [overOff] = true;
44 paintStatesEnabled [downOff] = true;
45 paintStatesEnabled [normalOn] = false;
46 paintStatesEnabled [overOn] = false;
47 paintStatesEnabled [downOn] = false;
48 paintStatesEnabled [background] = false;
50 parentClasses = "public Button";
52 for (int i = 7; --i >= 0;)
54 paintRoutines [i] = new PaintRoutine();
55 paintRoutines [i]->setDocument (this);
56 paintRoutines [i]->setBackgroundColour (Colours::transparentBlack);
60 ButtonDocument::~ButtonDocument()
62 for (int i = 7; --i >= 0;)
63 delete paintRoutines [i];
66 static const char* const stateNames[] =
68 "normal", "over", "down",
69 "normal on", "over on", "down on",
70 "common background"
73 int stateNameToIndex (const String& name)
75 for (int i = 7; --i >= 0;)
76 if (name.equalsIgnoreCase (stateNames[i]))
77 return i;
79 jassertfalse
80 return normalOff;
84 int ButtonDocument::getNumPaintRoutines() const
86 int n = 0;
88 for (int i = 7; --i >= 0;)
89 if (paintStatesEnabled [i])
90 ++n;
92 return n;
95 const StringArray ButtonDocument::getPaintRoutineNames() const
97 StringArray s;
99 for (int i = 0; i < 7; ++i)
100 if (paintStatesEnabled [i])
101 s.add (stateNames [i]);
103 return s;
106 PaintRoutine* ButtonDocument::getPaintRoutine (const int index) const
108 int n = 0;
110 for (int i = 0; i < 7; ++i)
112 if (paintStatesEnabled [i])
114 if (index == n)
115 return paintRoutines [i];
116 else
117 ++n;
121 jassertfalse
122 return 0;
125 void ButtonDocument::setStatePaintRoutineEnabled (const int index, bool b)
127 jassert (index > 0 && index < 7);
129 if (paintStatesEnabled [index] != b)
131 paintStatesEnabled [index] = b;
132 changed();
136 bool ButtonDocument::isStatePaintRoutineEnabled (const int index) const
138 return paintStatesEnabled [index];
141 int ButtonDocument::chooseBestEnabledPaintRoutine (int paintRoutineWanted) const
143 switch (paintRoutineWanted)
145 case normalOff:
146 return normalOff;
148 case overOff:
149 return paintStatesEnabled [overOff] ? overOff : normalOff;
151 case downOff:
152 return paintStatesEnabled [downOff] ? downOff : chooseBestEnabledPaintRoutine (overOff);
154 case normalOn:
155 return paintStatesEnabled [normalOn] ? normalOn : normalOff;
157 case overOn:
158 return paintStatesEnabled [overOn] ? overOn : (paintStatesEnabled [normalOn] ? normalOn : chooseBestEnabledPaintRoutine (overOff));
160 case downOn:
161 return paintStatesEnabled [downOn] ? downOn
162 : ((paintStatesEnabled [overOn] || paintStatesEnabled [normalOn])
163 ? chooseBestEnabledPaintRoutine (overOn)
164 : chooseBestEnabledPaintRoutine (downOff));
166 default:
167 jassertfalse
168 break;
171 return normalOff;
174 //==============================================================================
175 const String ButtonDocument::getTypeName() const
177 return "Button";
180 JucerDocument* ButtonDocument::createCopy()
182 ButtonDocument* newOne = new ButtonDocument();
184 newOne->resources = resources;
185 newOne->setFile (getFile());
187 XmlElement* const xml = createXml();
188 newOne->loadFromXml (*xml);
189 delete xml;
191 return newOne;
194 XmlElement* ButtonDocument::createXml() const
196 XmlElement* const doc = JucerDocument::createXml();
198 for (int i = 0; i < 7; ++i)
200 XmlElement* e = paintRoutines [i]->createXml();
201 e->setAttribute ("buttonState", stateNames [i]);
202 e->setAttribute ("enabled", paintStatesEnabled [i]);
204 doc->addChildElement (e);
207 return doc;
210 bool ButtonDocument::loadFromXml (const XmlElement& xml)
212 if (JucerDocument::loadFromXml (xml))
214 for (int i = 7; --i >= 0;)
215 paintStatesEnabled [i] = false;
217 forEachXmlChildElementWithTagName (xml, e, PaintRoutine::xmlTagName)
219 const int stateIndex = stateNameToIndex (e->getStringAttribute ("buttonState"));
221 paintRoutines [stateIndex]->loadFromXml (*e);
222 paintStatesEnabled [stateIndex] = e->getBoolAttribute ("enabled", stateIndex < normalOn);
225 changed();
226 getUndoManager().clearUndoHistory();
227 return true;
230 return false;
233 void ButtonDocument::getOptionalMethods (StringArray& baseClasses,
234 StringArray& returnValues,
235 StringArray& methods,
236 StringArray& initialContents) const
238 JucerDocument::getOptionalMethods (baseClasses, returnValues, methods, initialContents);
240 addMethod ("Button", "void", "clicked()", "", baseClasses, returnValues, methods, initialContents);
241 addMethod ("Button", "void", "buttonStateChanged()", "", baseClasses, returnValues, methods, initialContents);
244 //==============================================================================
245 class ButtonStatePaintEnabledProperty : public BooleanPropertyComponent,
246 private ChangeListener
248 public:
249 ButtonStatePaintEnabledProperty (const String& name, ButtonDocument& document_, const int stateMethod_)
250 : BooleanPropertyComponent (name, "enabled", "disabled"),
251 document (document_),
252 stateMethod (stateMethod_)
254 document.addChangeListener (this);
257 ~ButtonStatePaintEnabledProperty()
259 document.removeChangeListener (this);
262 void setState (bool newState)
264 document.setStatePaintRoutineEnabled (stateMethod, newState);
267 bool getState() const
269 return document.isStatePaintRoutineEnabled (stateMethod);
272 private:
273 void changeListenerCallback (ChangeBroadcaster*)
275 refresh();
278 ButtonDocument& document;
279 const int stateMethod;
282 void ButtonDocument::addExtraClassProperties (PropertyPanel* panel)
284 Array <PropertyComponent*> props;
286 for (int i = 1; i < 7; ++i)
287 props.add (new ButtonStatePaintEnabledProperty (stateNames[i], *this, i));
289 panel->addSection ("Button paint routines", props);
292 //==============================================================================
293 class ButtonTestComponent : public Button
295 public:
296 ButtonTestComponent (ButtonDocument* const document_, const bool alwaysFillBackground_)
297 : Button (String::empty),
298 document (document_),
299 alwaysFillBackground (alwaysFillBackground_)
301 setClickingTogglesState (true);
304 ~ButtonTestComponent()
308 void paintButton (Graphics& g, bool isMouseOverButton, bool isButtonDown)
310 if (document->paintStatesEnabled [background])
312 document->paintRoutines [background]->fillWithBackground (g, alwaysFillBackground);
313 document->paintRoutines [background]->drawElements (g, Rectangle<int> (0, 0, getWidth(), getHeight()));
316 const int stateIndex
317 = getToggleState()
318 ? (isButtonDown ? document->chooseBestEnabledPaintRoutine (downOn)
319 : (isMouseOverButton ? document->chooseBestEnabledPaintRoutine (overOn)
320 : document->chooseBestEnabledPaintRoutine (normalOn)))
321 : (isButtonDown ? document->chooseBestEnabledPaintRoutine (downOff)
322 : (isMouseOverButton ? document->chooseBestEnabledPaintRoutine (overOff)
323 : normalOff));
325 document->paintRoutines [stateIndex]->fillWithBackground (g, ! document->paintStatesEnabled [background]);
326 document->paintRoutines [stateIndex]->drawElements (g, Rectangle<int> (0, 0, getWidth(), getHeight()));
329 private:
330 ButtonDocument* const document;
331 const bool alwaysFillBackground;
334 Component* ButtonDocument::createTestComponent (const bool alwaysFillBackground)
336 return new ButtonTestComponent (this, alwaysFillBackground);
339 //==============================================================================
340 void ButtonDocument::fillInGeneratedCode (GeneratedCode& code) const
342 JucerDocument::fillInGeneratedCode (code);
344 code.parentClassInitialiser = "Button (" + quotedString (code.componentName) + ")";
345 code.removeCallback ("void", "paint (Graphics& g)");
348 void ButtonDocument::fillInPaintCode (GeneratedCode& code) const
350 jassert (paintStatesEnabled [normalOff]);
351 String paintCode [7];
353 for (int i = 0; i < 7; ++i)
354 if (paintStatesEnabled [i])
355 paintRoutines[i]->fillInGeneratedCode (code, paintCode [i]);
357 String& s = code.getCallbackCode ("public Button",
358 "void",
359 "paintButton (Graphics& g, bool isMouseOverButton, bool isButtonDown)",
360 false);
362 int numPaintRoutines = getNumPaintRoutines();
364 if (paintStatesEnabled [background])
366 s << paintCode [background] << "\n";
367 --numPaintRoutines;
370 if (numPaintRoutines == 1)
372 s << paintCode [normalOff];
374 else if (numPaintRoutines == downOff && (paintStatesEnabled [overOff] || paintStatesEnabled [downOff] || paintStatesEnabled [normalOn]))
376 if (paintStatesEnabled [normalOn])
378 s << "if (getToggleState())\n{\n "
379 << indentCode (paintCode [normalOn], 4).trimEnd();
381 else if (paintStatesEnabled [overOff])
383 s << "if (isButtonDown || isMouseOverButton)\n{\n "
384 << indentCode (paintCode [overOff], 4).trimEnd();
386 else
388 s << "if (isButtonDown)\n{\n "
389 << indentCode (paintCode [downOff], 4).trimEnd();
392 s << "\n}\nelse\n{\n "
393 << indentCode (paintCode [normalOff], 4).trimEnd()
394 << "\n}\n";
396 else if (numPaintRoutines == normalOn && paintStatesEnabled [overOff] && paintStatesEnabled [downOff])
398 s << "if (isButtonDown)\n{\n "
399 << indentCode (paintCode [downOff], 4).trimEnd()
400 << "\n}\nelse if (isMouseOverButton)\n{\n "
401 << indentCode (paintCode [overOff], 4).trimEnd()
402 << "\n}\nelse\n{\n "
403 << indentCode (paintCode [normalOff], 4).trimEnd()
404 << "\n}\n";
406 else
408 if (paintStatesEnabled [normalOn] || paintStatesEnabled [overOn] || paintStatesEnabled [downOn])
410 s << "switch (getToggleState() ? (isButtonDown ? "
411 << chooseBestEnabledPaintRoutine (downOn) << " : (isMouseOverButton ? "
412 << chooseBestEnabledPaintRoutine (overOn) << " : "
413 << chooseBestEnabledPaintRoutine (normalOn) << "))\n : (isButtonDown ? "
414 << chooseBestEnabledPaintRoutine (downOff) << " : (isMouseOverButton ? "
415 << chooseBestEnabledPaintRoutine (overOff) << " : 0)))\n{\n";
417 else
419 s << "switch (isButtonDown ? " << chooseBestEnabledPaintRoutine (downOff)
420 << " : (isMouseOverButton ? " << chooseBestEnabledPaintRoutine (overOff)
421 << " : 0))\n{\n";
424 for (int i = 0; i < 6; ++i)
426 if (paintStatesEnabled [i])
428 s << "case " << i << ":\n {\n "
429 << indentCode (paintCode [i], 8).trimEnd()
430 << "\n break;\n }\n\n";
434 s << "default:\n break;\n}\n";